import { reactive } from 'vue'
import { defineStore } from 'pinia'
import { TYPES, on } from '@/utils/state-broadcast'
import { useInfinite } from '@/compositions/request/infinite'
import { FEED_PERMISION } from '@/constant'
import API from '@/http'

export const useCreatorStore = defineStore('creator', () => {
  /**
   * {
   *   [id]: {
   *     後端傳來的內容
   *   },
   *   ...
   * }
   */
  const creatorsMap = reactive(new Map())

  /**
   * {
   *   [id]: {
   *     video: useInfinite({}),
   *     photo: useInfinite({}),
   *     shop: useInfinite({})
   *   },
   *   ...
   * }
   */
  const creatorsMediaMap = reactive(new Map())

  const inRequesting = {}

  async function getCreator(id) {
    if (typeof id !== 'number') {
      throw new Error('creator id only accept number type.')
    }

    if (creatorsMap.has(id)) {
      return creatorsMap.get(id)
    }

    if (inRequesting[id]) {
      await inRequesting[id]
      return creatorsMap.get(id)
    }

    inRequesting[id] = API.Auth.detail({ data: { aff: id } })
      .then((d) => creatorsMap.set(id, d))
      .finally(() => {
        if (inRequesting[id]) {
          delete inRequesting[id]
        }
      })

    await inRequesting[id]
    return creatorsMap.get(id)
  }

  function getMedia(id) {
    if (id === undefined || id === null) {
      return {}
    }

    if (!creatorsMediaMap.has(id)) {
      creatorsMediaMap.set(id, {
        free: useInfinite({
          request: API.Media.getPostList,
          params: { aff: id, visible: FEED_PERMISION.ALL },
        }),
        subs: useInfinite({
          request: API.Media.getPostList,
          params: { aff: id, visible: FEED_PERMISION.SUB },
        }),
        shop: useInfinite({
          request: API.Media.getPostList,
          params: { aff: id, visible: FEED_PERMISION.SHOP },
        }),
      })
    }

    return creatorsMediaMap.get(id)
  }

  function clear() {
    Promise.allSettled(Object.values(inRequesting)).then(() => {
      creatorsMap.clear()
      creatorsMediaMap.clear()
    })
  }

  on(TYPES.FOLLOW, (id, isFollow) => {
    if (!creatorsMap.has(id)) {
      console.warn(`There is no creator ${id} before client trigger follow?????`)
      return
    }

    const creator = creatorsMap.get(id)
    creator.is_follow = isFollow
    creator.follow += isFollow ? 1 : -1
  })

  on(TYPES.SUB, (id, isSubscribe) => {
    if (!creatorsMap.has(id)) {
      console.warn(`There is no creator ${id} before client trigger subscribe?????`)
      return
    }

    const creator = creatorsMap.get(id)
    creator.is_subscribe = isSubscribe
    creator.subscribe += isSubscribe ? 1 : -1
  })

  on(TYPES.BLOCK, (id, isBlock) => {
    if (!creatorsMap.has(id)) {
      console.warn(`There is no creator ${id} before client trigger block/unblock?????`)
      return
    }

    const creator = creatorsMap.get(id)
    creator.is_block = isBlock
  })

  return {
    getCreator,
    getMedia,
    clear,
  }
})
